﻿using Dto;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Distributed;
using Model;
using System.Text.Json;

namespace Dlpad.Services
{
    public class DictDataService : IDictDataService
    {
        private readonly ApplicationDbContext _context;
        private readonly IDistributedCache _cache;
        private readonly TimeSpan _cacheExpiration = TimeSpan.FromHours(1);

        public DictDataService(ApplicationDbContext context, IDistributedCache cache)
        {
            _context = context;
            _cache = cache;
        }

        public async Task<List<DictDataResponseDto>> GetDictDataByTypeAsync(string dictType)
        {
            try
            {
                var cacheKey = $"Dlpad_dict_data_{dictType?.Trim().ToLower()}";
                Console.WriteLine($"[DICT-DATA-CACHE] 使用缓存键: {cacheKey}");

                // 先尝试获取缓存
                string cachedData = null;
                try
                {
                    cachedData = await _cache.GetStringAsync(cacheKey);
                }
                catch (Exception ex) when (ex.Message.Contains("WRONGTYPE"))
                {
                    // 如果是类型错误，忽略并继续数据库查询
                    Console.WriteLine($"[CACHE-IGNORE] 忽略 hash 类型缓存，继续查询数据库: {ex.Message}");
                    cachedData = null;
                }

                // 如果获取到数据，直接返回
                if (!string.IsNullOrEmpty(cachedData))
                {
                    Console.WriteLine($"[DICT-DATA-CACHE] 缓存命中: {cacheKey}");
                    try
                    {
                        var result = JsonSerializer.Deserialize<List<DictDataResponseDto>>(cachedData);
                        Console.WriteLine($"[DICT-DATA-CACHE] 返回 {result?.Count ?? 0} 条数据");
                        return result ?? new List<DictDataResponseDto>();
                    }
                    catch (JsonException ex)
                    {
                        Console.WriteLine($"[DICT-DATA-CACHE] 缓存数据反序列化失败: {ex.Message}");
                        // 删除损坏的缓存
                        await _cache.RemoveAsync(cacheKey);
                    }
                }

                Console.WriteLine($"[DICT-DATA-CACHE] 缓存未命中: {dictType}");

                // 从数据库获取
                var dictData = await GetDictDataFromDbAsync(dictType);
                Console.WriteLine($"[DICT-DATA-CACHE] 数据库返回 {dictData.Count} 条数据");

                // 存入缓存（让框架决定存储类型）
                if (dictData.Any())
                {
                    try
                    {
                        var jsonData = JsonSerializer.Serialize(dictData);
                        Console.WriteLine($"[CACHE-WRITE] 准备写入缓存，JSON长度: {jsonData.Length}");

                        var cacheOptions = new DistributedCacheEntryOptions
                        {
                            AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1)
                        };

                        await _cache.SetStringAsync(cacheKey, jsonData, cacheOptions);
                        Console.WriteLine($"[CACHE-WRITE] 缓存写入成功: {cacheKey}");

                        // 验证写入
                        await VerifyCacheType(cacheKey);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"[CACHE-ERROR] 缓存写入异常: {ex.Message}");
                        Console.WriteLine($"[CACHE-ERROR] 异常类型: {ex.GetType()}");
                    }
                }

                return dictData;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"[DICT-DATA-CACHE] 总体异常: {ex.Message}");
                return new List<DictDataResponseDto>();
            }
        }

        // 添加缓存类型验证方法
        private async Task VerifyCacheType(string cacheKey)
        {
            try
            {
                // 重新获取数据验证
                var verifyData = await _cache.GetStringAsync(cacheKey);
                if (!string.IsNullOrEmpty(verifyData))
                {
                    Console.WriteLine($"[CACHE-VERIFY] 缓存验证成功，数据长度: {verifyData.Length}");
                }
                else
                {
                    Console.WriteLine($"[CACHE-VERIFY] 缓存验证失败 - 写入后读取为空");
                }
            }
            catch (Exception ex) when (ex.Message.Contains("WRONGTYPE"))
            {
                // 如果是 hash 类型，说明是框架默认行为，不是错误
                Console.WriteLine($"[CACHE-VERIFY] 缓存为 hash 类型（框架默认行为）");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"[CACHE-VERIFY] 缓存验证异常: {ex.Message}");
            }
        }

        private async Task<List<DictDataResponseDto>> GetDictDataFromDbAsync(string dictType)
        {
            return await _context.SysDictDatas
                .Where(x => x.DictType == dictType && x.Status == "0")
                .OrderBy(x => x.DictSort)
                .Select(x => new DictDataResponseDto
                {
                    DictCode = x.DictCode,
                    DictLabel = x.DictLabel,
                    DictSort = x.DictSort,
                    DictValue = x.DictValue,
                    DictType = x.DictType,
                    CssClass = x.CssClass,
                    ListClass = x.ListClass,
                    IsDefault = x.IsDefault,
                    Status = x.Status,
                    Remark = x.Remark,
                })
                .ToListAsync();
        }

        public async Task<List<DictOptionDto>> GetDictOptionsAsync(string dictType)
        {
            try
            {
                var dictData = await GetDictDataByTypeAsync(dictType);

                return dictData.Select(x => new DictOptionDto
                {
                    Label = x.DictLabel,
                    Value = x.DictValue,
                    Disabled = x.IsDefault != "0",
                    ClassName = x.CssClass,
                    IsDefault = x.IsDefault == "Y"
                }).ToList();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"GetDictOptionsAsync 错误: {ex.Message}");
                return new List<DictOptionDto>();
            }
        }

        public async Task<string?> GetDictValueByLabelAsync(string dictType, string dictLabel)
        {
            var dictData = await GetDictDataByTypeAsync(dictType);
            return dictData.FirstOrDefault(x => x.DictLabel == dictLabel)?.DictValue;
        }

        public async Task<string?> GetDictLabelByValuesAsync(string dictType, string dictValue)
        {
            var dictData = await GetDictDataByTypeAsync(dictType);
            return dictData.FirstOrDefault(x => x.DictValue == dictValue)?.DictLabel;
        }

        public async Task<Dictionary<string, List<DictOptionDto>>> GetMultipleDictOptions(List<string> dictTypes)
        {
            var result = new Dictionary<string, List<DictOptionDto>>();

            foreach (var dictType in dictTypes)
            {
                try
                {
                    var options = await GetDictOptionsAsync(dictType);
                    result[dictType] = options;
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"获取字典类型 {dictType} 的选项失败: {ex.Message}");
                    result[dictType] = new List<DictOptionDto>();
                }
            }

            return result;
        }

        public async Task<PagedResultDto<DictDataResponseDto>> GetDictDataListAsync(DictDataQueryDto query)
        {
            try
            {
                // 生成缓存键
                var cacheKey = $"Dlpad_dict_data_list_{query.DictType}_{query.DictLabel}_{query.DictValue}_{query.Status}_{query.PageNumber}_{query.PageSize}";
                Console.WriteLine($"[DICT-DATA-LIST-CACHE] 使用缓存键: {cacheKey}");

                // 尝试从缓存获取
                string cachedData = null;
                try
                {
                    cachedData = await _cache.GetStringAsync(cacheKey);
                }
                catch (Exception ex) when (ex.Message.Contains("WRONGTYPE"))
                {
                    Console.WriteLine($"[CACHE-IGNORE] 忽略 hash 类型缓存: {cacheKey}");
                    cachedData = null;
                }

                if (!string.IsNullOrEmpty(cachedData))
                {
                    Console.WriteLine($"[DICT-DATA-LIST-CACHE] 缓存命中: {cacheKey}");
                    try
                    {
                        return JsonSerializer.Deserialize<PagedResultDto<DictDataResponseDto>>(cachedData);
                    }
                    catch (JsonException)
                    {
                        Console.WriteLine($"[DICT-DATA-LIST-CACHE] 缓存数据反序列化失败");
                        await _cache.RemoveAsync(cacheKey);
                    }
                }

                Console.WriteLine($"[DICT-DATA-LIST-CACHE] 缓存未命中，查询数据库");

                var queryable = _context.SysDictDatas.AsQueryable();

                if (!string.IsNullOrWhiteSpace(query.DictLabel))
                {
                    queryable = queryable.Where(x => x.DictLabel.Contains(query.DictLabel));
                }

                if (!string.IsNullOrWhiteSpace(query.DictValue))
                {
                    queryable = queryable.Where(x => x.DictValue.Contains(query.DictValue));
                }

                if (!string.IsNullOrWhiteSpace(query.DictType))
                {
                    queryable = queryable.Where(x => x.DictType == query.DictType);
                }

                if (!string.IsNullOrWhiteSpace(query.Status))
                {
                    queryable = queryable.Where(x => x.Status == query.Status);
                }

                var totalCount = await queryable.CountAsync();

                var items = await queryable
                    .OrderBy(x => x.DictSort)
                    .Skip((query.PageNumber - 1) * query.PageSize)
                    .Take(query.PageSize)
                    .Select(x => new DictDataResponseDto
                    {
                        DictCode = x.DictCode,
                        DictLabel = x.DictLabel,
                        DictValue = x.DictValue,
                        DictSort = x.DictSort,
                        DictType = x.DictType,
                        CssClass = x.CssClass,
                        ListClass = x.ListClass,
                        IsDefault = x.IsDefault,
                        Status = x.Status,
                        Remark = x.Remark,
                        CreateTime = x.CreateTime
                    })
                    .ToListAsync();

                var result = new PagedResultDto<DictDataResponseDto>
                {
                    TotalCount = totalCount,
                    Items = items,
                    PageNumber = query.PageNumber,
                    PageSize = query.PageSize
                };

                // 将结果存入缓存（分页查询缓存时间较短）
                try
                {
                    var cacheOptions = new DistributedCacheEntryOptions
                    {
                        AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5) // 5分钟
                    };

                    await _cache.SetStringAsync(cacheKey, JsonSerializer.Serialize(result), cacheOptions);
                    Console.WriteLine($"[DICT-DATA-LIST-CACHE] 分页缓存写入成功: {cacheKey}");
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"[DICT-DATA-LIST-CACHE] 分页缓存写入失败: {ex.Message}");
                }

                return result;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取字典数据列表失败: {ex.Message}");
                throw;
            }
        }

        public async Task<SysDictData?> GetDictDataByIdAsync(long id)
        {
            return await _context.SysDictDatas.FindAsync(id);
        }

        public async Task<bool> CreateDictDataAsync(SysDictData dictData)
        {
            try
            {
                _context.SysDictDatas.Add(dictData);
                await _context.SaveChangesAsync();

                await ClearDictDataCacheAsync(dictData.DictType);//清除对应字典类型的缓存
                ClearDictDataListCache(); // 清除所有分页缓存

                return true;
            }
            catch
            {
                return false;
            }
        }

        public async Task<bool> UpdateDictDataAsync(SysDictData dictData)
        {
            try
            {
                _context.SysDictDatas.Update(dictData);
                await _context.SaveChangesAsync();

                await ClearDictDataCacheAsync(dictData.DictType);//清除对应字典类型的缓存
                ClearDictDataListCache(); // 清除所有分页缓存
                return true;
            }
            catch
            {
                return false;
            }
        }

        public async Task<bool> DeleteDictDataAsync(long id)
        {
            try
            {
                var dictData = await _context.SysDictDatas.FindAsync(id);
                if (dictData == null) return true;

                var dictType = dictData.DictType;
                _context.SysDictDatas.Remove(dictData);
                await _context.SaveChangesAsync();

                await ClearDictDataCacheAsync(dictType);//清除对应字典类型的缓存
                 ClearDictDataListCache(); // 清除所有分页缓存
                return true;
            }
            catch
            {
                return false;
            }
        }

        public async Task ClearDictDataCacheAsync(string dictType = null)
        {
            try
            {
                if (string.IsNullOrEmpty(dictType))
                {
                    // 清除所有字典数据缓存
                    var allDictTypes = await _context.SysDictTypes
                        .Where(x => x.Status == "0")
                        .Select(x => x.DictType)
                        .ToListAsync();

                    foreach (var type in allDictTypes)
                    {
                        await _cache.RemoveAsync($"Dlpad_dict_data_{type}");
                    }
                }
                else
                {
                    await _cache.RemoveAsync($"Dlpad_dict_data_{dictType}");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"清除字典数据缓存失败: {ex.Message}");
            }
        }

       
        private void ClearDictDataListCache()
        {
            try
            {
                Console.WriteLine($"[CACHE-CLEAR] 清除字典数据分页缓存");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"清除字典数据分页缓存失败: {ex.Message}");
            }
        }
    }
}